#!/usr/bin/env python3
"""
Ford URL0 逆向分析脚本
分析 https://www.ford.co.uk/cars/model#focus
寻找车款信息和 "See Full Specification" 内容
"""

import json
import time
import sys
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException

# 添加src目录到路径
sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))

class FordURL0ReverseAnalyzer:
    """Ford URL0 逆向分析器"""
    
    def __init__(self):
        self.driver = None
        self.wait = None
        self.url0 = None
        self.results = {
            "analysis_date": time.strftime("%Y-%m-%d %H:%M:%S"),
            "target_url": "",
            "page_analysis": {},
            "vehicle_models": [],
            "specification_sources": [],
            "api_endpoints_discovered": [],
            "findings": {}
        }
    
    def load_config(self):
        """加载配置文件获取URL0"""
        try:
            with open('fetchNgc2.json', 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            self.url0 = config.get('sub_model', {}).get('url0')
            if not self.url0:
                print("❌ 未找到url0配置")
                return False
            
            self.results["target_url"] = self.url0
            print(f"✅ 目标URL: {self.url0}")
            return True
            
        except Exception as e:
            print(f"❌ 加载配置失败: {e}")
            return False
    
    def setup_driver(self):
        """初始化WebDriver"""
        try:
            print("🔧 初始化Chrome WebDriver...")
            
            options = Options()
            options.add_argument('--no-sandbox')
            options.add_argument('--disable-dev-shm-usage')
            options.add_argument('--disable-gpu')
            options.add_argument('--window-size=1920,1080')
            
            # 启用网络日志
            options.add_argument('--enable-logging')
            options.add_argument('--log-level=0')
            
            # 启用Performance和Network域
            options.add_experimental_option('useAutomationExtension', False)
            options.add_experimental_option("excludeSwitches", ["enable-automation"])
            options.add_argument("--disable-blink-features=AutomationControlled")
            
            # 设置User-Agent
            options.add_argument('--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
            
            self.driver = webdriver.Chrome(options=options)
            self.wait = WebDriverWait(self.driver, 15)
            
            # 启用Chrome DevTools Protocol
            self.driver.execute_cdp_cmd('Network.enable', {})
            self.driver.execute_cdp_cmd('Page.enable', {})
            
            print("✅ WebDriver初始化成功")
            return True
            
        except Exception as e:
            print(f"❌ WebDriver初始化失败: {e}")
            return False
    
    def navigate_to_url0(self):
        """导航到URL0并分析页面"""
        try:
            print(f"🌐 导航到: {self.url0}")
            self.driver.get(self.url0)
            
            # 等待页面加载
            time.sleep(5)
            
            # 基础页面信息
            page_title = self.driver.title
            current_url = self.driver.current_url
            
            self.results["page_analysis"] = {
                "title": page_title,
                "final_url": current_url,
                "url_changed": current_url != self.url0
            }
            
            print(f"📄 页面标题: {page_title}")
            print(f"📍 最终URL: {current_url}")
            
            if current_url != self.url0:
                print("⚠️  URL发生了重定向")
            
            return True
            
        except Exception as e:
            print(f"❌ 导航失败: {e}")
            return False
    
    def discover_vehicle_models(self):
        """发现页面上的车款信息"""
        try:
            print("🔍 分析车款信息...")
            
            # 多种选择器尝试找到车款
            model_selectors = [
                # 基于常见的车款展示模式
                'div[class*="vehicle"], div[class*="model"], div[class*="car"]',
                'a[href*="focus"], a[href*="model"]',
                '.product-tile, .model-tile, .vehicle-tile',
                'h2, h3, h4',  # 标题元素
                '[data-model], [data-vehicle], [data-product]',
                'button[class*="spec"], a[class*="spec"]'  # 规格按钮
            ]
            
            models_found = []
            
            for selector in model_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    print(f"  📋 选择器 '{selector}' 找到 {len(elements)} 个元素")
                    
                    for elem in elements[:10]:  # 限制每个选择器最多10个元素
                        try:
                            text = elem.text.strip()
                            href = elem.get_attribute('href') if elem.tag_name == 'a' else None
                            data_attrs = {}
                            
                            # 获取data-*属性 (简化版本)
                            try:
                                # 尝试常见的data属性
                                for common_attr in ['data-model', 'data-vehicle', 'data-product', 'data-cy']:
                                    try:
                                        value = elem.get_attribute(common_attr)
                                        if value:
                                            data_attrs[common_attr] = value
                                    except:
                                        continue
                            except:
                                pass
                            
                            if text and len(text) > 2:
                                model_info = {
                                    "text": text,
                                    "tag": elem.tag_name,
                                    "selector_used": selector,
                                    "href": href,
                                    "data_attributes": data_attrs,
                                    "class": elem.get_attribute('class')
                                }
                                models_found.append(model_info)
                                
                        except Exception as e:
                            continue
                
                except Exception as e:
                    print(f"    ❌ 选择器失败: {e}")
                    continue
            
            # 去重和过滤
            unique_models = []
            seen_texts = set()
            
            for model in models_found:
                text = model['text'].lower()
                if text not in seen_texts and len(text) > 2:
                    seen_texts.add(text)
                    unique_models.append(model)
            
            self.results["vehicle_models"] = unique_models[:20]  # 保留前20个
            print(f"✅ 发现 {len(unique_models)} 个潜在车款信息")
            
            return unique_models
            
        except Exception as e:
            print(f"❌ 车款发现失败: {e}")
            return []
    
    def find_specification_links(self):
        """寻找 "See Full Specification" 或类似的链接"""
        try:
            print("🔍 寻找规格说明链接...")
            
            # 多种可能的规格链接文本
            spec_keywords = [
                'specification', 'spec', 'full spec', 'see full specification',
                'details', 'more details', 'view details',
                'configure', 'build', 'explore',
                'learn more', 'find out more'
            ]
            
            spec_sources = []
            
            # 查找包含规格关键词的链接和按钮
            for keyword in spec_keywords:
                try:
                    # 使用XPath查找包含关键词的元素
                    xpath = f"//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '{keyword}')]"
                    elements = self.driver.find_elements(By.XPATH, xpath)
                    
                    print(f"  🔍 关键词 '{keyword}' 找到 {len(elements)} 个元素")
                    
                    for elem in elements:
                        try:
                            text = elem.text.strip()
                            href = elem.get_attribute('href')
                            onclick = elem.get_attribute('onclick')
                            data_attrs = {}
                            
                            # 获取data-*属性 (简化版本)
                            try:
                                # 尝试常见的data属性
                                for common_attr in ['data-model', 'data-vehicle', 'data-product', 'data-cy', 'data-action']:
                                    try:
                                        value = elem.get_attribute(common_attr)
                                        if value:
                                            data_attrs[common_attr] = value
                                    except:
                                        continue
                            except:
                                pass
                            
                            spec_info = {
                                "text": text,
                                "keyword_matched": keyword,
                                "tag": elem.tag_name,
                                "href": href,
                                "onclick": onclick,
                                "data_attributes": data_attrs,
                                "class": elem.get_attribute('class'),
                                "id": elem.get_attribute('id')
                            }
                            
                            spec_sources.append(spec_info)
                            
                        except Exception as e:
                            continue
                            
                except Exception as e:
                    print(f"    ❌ 关键词 '{keyword}' 搜索失败: {e}")
                    continue
            
            # 去重
            unique_specs = []
            seen_texts = set()
            
            for spec in spec_sources:
                text = spec['text'].lower()
                if text not in seen_texts and len(text) > 2:
                    seen_texts.add(text)
                    unique_specs.append(spec)
            
            self.results["specification_sources"] = unique_specs[:15]  # 保留前15个
            print(f"✅ 发现 {len(unique_specs)} 个潜在规格链接")
            
            return unique_specs
            
        except Exception as e:
            print(f"❌ 规格链接搜索失败: {e}")
            return []
    
    def monitor_network_requests(self):
        """监控网络请求，寻找API端点"""
        try:
            print("🔍 监控网络请求...")
            
            # 获取所有网络日志
            logs = self.driver.get_log('performance')
            api_endpoints = []
            
            for log in logs:
                try:
                    message = json.loads(log['message'])
                    if message.get('message', {}).get('method') == 'Network.responseReceived':
                        response = message['message']['params']['response']
                        url = response.get('url', '')
                        
                        # 过滤出可能的API端点
                        if any(keyword in url.lower() for keyword in ['api', 'service', 'data', 'json', 'ajax']):
                            endpoint_info = {
                                "url": url,
                                "status": response.get('status'),
                                "method": response.get('method', 'GET'),
                                "mime_type": response.get('mimeType'),
                                "timestamp": log['timestamp']
                            }
                            api_endpoints.append(endpoint_info)
                            
                except Exception as e:
                    continue
            
            # 去重
            unique_endpoints = []
            seen_urls = set()
            
            for endpoint in api_endpoints:
                url = endpoint['url']
                if url not in seen_urls:
                    seen_urls.add(url)
                    unique_endpoints.append(endpoint)
            
            self.results["api_endpoints_discovered"] = unique_endpoints
            print(f"✅ 发现 {len(unique_endpoints)} 个潜在API端点")
            
            return unique_endpoints
            
        except Exception as e:
            print(f"❌ 网络监控失败: {e}")
            return []
    
    def test_specification_interaction(self):
        """测试点击规格链接的交互"""
        try:
            print("🎯 测试规格链接交互...")
            
            spec_sources = self.results.get("specification_sources", [])
            interaction_results = []
            
            for i, spec in enumerate(spec_sources[:3]):  # 只测试前3个
                try:
                    print(f"  🔗 测试规格链接 {i+1}: {spec['text']}")
                    
                    # 尝试找到并点击元素
                    if spec['id']:
                        element = self.driver.find_element(By.ID, spec['id'])
                    elif spec['class']:
                        element = self.driver.find_element(By.CLASS_NAME, spec['class'].split()[0])
                    else:
                        # 使用文本查找
                        element = self.driver.find_element(By.XPATH, f"//*[contains(text(), '{spec['text']}')]")
                    
                    # 记录点击前状态
                    before_url = self.driver.current_url
                    
                    # 点击
                    self.driver.execute_script("arguments[0].click();", element)
                    time.sleep(3)
                    
                    # 记录点击后状态
                    after_url = self.driver.current_url
                    
                    result = {
                        "spec_info": spec,
                        "before_url": before_url,
                        "after_url": after_url,
                        "url_changed": before_url != after_url,
                        "success": True
                    }
                    
                    interaction_results.append(result)
                    
                    # 如果URL改变了，分析新页面
                    if before_url != after_url:
                        print(f"    ✅ URL改变: {after_url}")
                        time.sleep(2)
                        
                        # 回到原页面准备下次测试
                        self.driver.back()
                        time.sleep(2)
                    
                except Exception as e:
                    result = {
                        "spec_info": spec,
                        "error": str(e),
                        "success": False
                    }
                    interaction_results.append(result)
                    print(f"    ❌ 交互失败: {e}")
            
            self.results["findings"]["interaction_tests"] = interaction_results
            return interaction_results
            
        except Exception as e:
            print(f"❌ 交互测试失败: {e}")
            return []
    
    def analyze_page_structure(self):
        """分析页面结构"""
        try:
            print("🔍 分析页面结构...")
            
            # 获取页面的主要结构信息
            structure_info = {
                "total_links": len(self.driver.find_elements(By.TAG_NAME, 'a')),
                "total_buttons": len(self.driver.find_elements(By.TAG_NAME, 'button')),
                "total_forms": len(self.driver.find_elements(By.TAG_NAME, 'form')),
                "has_react": "react" in self.driver.page_source.lower(),
                "has_angular": "angular" in self.driver.page_source.lower(),
                "has_vue": "vue" in self.driver.page_source.lower(),
                "scripts_count": len(self.driver.find_elements(By.TAG_NAME, 'script'))
            }
            
            # 查找可能的车款容器
            container_selectors = [
                '[class*="container"]',
                '[class*="wrapper"]', 
                '[class*="grid"]',
                '[class*="list"]',
                'main, section, article'
            ]
            
            containers_found = []
            for selector in container_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        containers_found.append({
                            "selector": selector,
                            "count": len(elements)
                        })
                except:
                    continue
            
            structure_info["containers"] = containers_found
            self.results["findings"]["page_structure"] = structure_info
            
            print(f"✅ 页面结构分析完成")
            return structure_info
            
        except Exception as e:
            print(f"❌ 页面结构分析失败: {e}")
            return {}
    
    def save_results(self):
        """保存分析结果"""
        try:
            output_file = "./release/url0_reverse_analysis.json"
            
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(self.results, f, ensure_ascii=False, indent=2)
            
            print(f"💾 分析结果已保存到: {output_file}")
            return output_file
            
        except Exception as e:
            print(f"❌ 保存结果失败: {e}")
            return None
    
    def cleanup(self):
        """清理资源"""
        if self.driver:
            self.driver.quit()
            print("🧹 WebDriver已关闭")
    
    def run_analysis(self):
        """运行完整分析"""
        try:
            print("🚀 开始Ford URL0逆向分析...")
            print("=" * 50)
            
            # 1. 加载配置
            if not self.load_config():
                return False
            
            # 2. 初始化WebDriver
            if not self.setup_driver():
                return False
            
            # 3. 导航到目标页面
            if not self.navigate_to_url0():
                return False
            
            # 4. 分析页面结构
            self.analyze_page_structure()
            
            # 5. 发现车款信息
            self.discover_vehicle_models()
            
            # 6. 寻找规格链接
            self.find_specification_links()
            
            # 7. 监控网络请求
            self.monitor_network_requests()
            
            # 8. 测试交互
            self.test_specification_interaction()
            
            # 9. 保存结果
            output_file = self.save_results()
            
            # 10. 打印摘要
            self.print_summary()
            
            return True
            
        except Exception as e:
            print(f"❌ 分析过程中出现错误: {e}")
            return False
        finally:
            self.cleanup()
    
    def print_summary(self):
        """打印分析摘要"""
        print("\n" + "=" * 50)
        print("📊 分析摘要")
        print("=" * 50)
        
        print(f"🎯 目标URL: {self.results['target_url']}")
        print(f"📄 页面标题: {self.results['page_analysis'].get('title', 'N/A')}")
        print(f"🚗 发现车款信息: {len(self.results['vehicle_models'])} 个")
        print(f"📋 发现规格链接: {len(self.results['specification_sources'])} 个")
        print(f"🔗 发现API端点: {len(self.results['api_endpoints_discovered'])} 个")
        
        # 显示前几个重要发现
        if self.results['vehicle_models']:
            print(f"\n🚗 主要车款信息:")
            for i, model in enumerate(self.results['vehicle_models'][:5]):
                print(f"  {i+1}. {model['text']} ({model['tag']})")
        
        if self.results['specification_sources']:
            print(f"\n📋 主要规格链接:")
            for i, spec in enumerate(self.results['specification_sources'][:5]):
                print(f"  {i+1}. {spec['text']} -> {spec['href'] or '(JS action)'}")
        
        if self.results['api_endpoints_discovered']:
            print(f"\n🔗 发现的API端点:")
            for i, endpoint in enumerate(self.results['api_endpoints_discovered'][:5]):
                print(f"  {i+1}. {endpoint['url'][:80]}...")

def main():
    """主函数"""
    analyzer = FordURL0ReverseAnalyzer()
    success = analyzer.run_analysis()
    
    if success:
        print("\n🎉 URL0逆向分析完成！")
        print("📁 请查看 ./release/url0_reverse_analysis.json 获取详细结果")
    else:
        print("\n❌ URL0逆向分析失败")
    
    return success

if __name__ == "__main__":
    main()
